package com.dcivision.dms.core;

import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.dcivision.dms.web.ListDmsDocumentForm;
import com.dcivision.framework.TextUtility;

/**
 * <p>Class Name:       ParseQueryRecordXML.java    </p>
 * <p>Description:      The class mainly convert the query xml back to search criteria form</p>
 * @author              Jenny Li
 * @company             DCIVision Limited
 * @creation date       06/09/2004
 * @version             $Revision: 1.18 $
 */

public class ParseQueryRecordXML {

  public static final String REVISION = "$Revision: 1.18 $";


  protected Log log = LogFactory.getLog(this.getClass().getName());
  Vector v;

  /**
   *  Constructor - Creates a new instance of ParseQueryRecordXML
   */
  public ParseQueryRecordXML() {
  }
   
 /**
  * Sets the ListDmsDocumentForm form object with the search criteria by the query
  * xml in stringBuffer.
  * 
  * <P>
  * The saved query xml in the stringBuffer converted the saved search criteria 
  * back to the search criteria in the ListDmsDocumentForm form.
  * </P>
  * 
  * @param form ActionForm object to store the search criteria
  * @param request  HttpServletRequest
  * @param sb Saved search criteria in xml format
  * @see com.dcivision.dms.web.ListDmsDocumentForm
  */ 
  public void getParseing(ActionForm form,HttpServletRequest request,StringBuffer sb){
    ListDmsDocumentForm maintForm=(ListDmsDocumentForm)form;
    Document doc=null;
    //File file=new File(locMaster.getLocPath()+"/query_"+this.getSessionContainer(request).getUserRecordID.toString+".xml");
    try{    
      doc=this.parse(sb);
      this.setFormData(doc,maintForm,request);     
    }catch(ParserConfigurationException ex){
      log.error(ex,ex);
    }catch(IOException ex){
      log.error(ex,ex);
    }catch(SAXException ex){
      log.error(ex,ex);
    }
  }
   
  /**
   * Parse the saved search criteria stored in StringBuffer in xml format to the org.w3c.dom.Document
   * 
   * @param sb saved search criteria stored in StringBuffer in xml format
   * @return org.w3c.dom.Document object that store the search criteria
   * @throws SAXException
   * @throws IOException
   * @throws ParserConfigurationException
   */
  public Document parse(StringBuffer sb) throws SAXException,IOException,ParserConfigurationException{
     DocumentBuilderFactory docFactory=DocumentBuilderFactory.newInstance();
     DocumentBuilder docBuilder=docFactory.newDocumentBuilder();
     docBuilder.setErrorHandler(new ErrorHandler(){
       public void error(SAXParseException e) throws SAXException{
         log.error("A error occured at line "+e.getLineNumber()+" Error Message: "+e.getMessage());
       }
       public void fatalError(SAXParseException e) throws SAXException{
         log.error("A fatal error occured at line "+e.getLineNumber()+" Fatal error Message: "+e.getMessage());
       }
       public void warning (SAXParseException e) throws SAXException{
         log.error("A waringing occured at line "+e.getLineNumber()+" Warning Message: "+e.getMessage());
       }
     });
     StringReader reader = new StringReader(sb.toString());
     InputSource inputSource = new InputSource(reader);
     Document document=docBuilder.parse(inputSource);
     return document;
   }
  
  /**
   * Sets the search criteria in the org.w3c.dom.Document object into the form object 
   * 
   * @param doc
   * @param maintForm
   * @param request
   * @see com.dcivision.dms.web.ListDmsDocumentForm
   * @see org.w3c.dom.Document
   */
  protected void setFormData(Document doc,ListDmsDocumentForm maintForm,HttpServletRequest request){
     NodeList rootList=doc.getElementsByTagName("root");
     List seList=new ArrayList(); 
     Vector v1=new Vector();
     //int k=0;
     for(int i=0;i<rootList.getLength();i++){
       Element rootNode=(Element)rootList.item(i);
       //String rootValue=parseXML.getTagValue("root",rootNode);
       String rootID= rootNode.getAttribute("id");
       String rootSelValue=rootNode.getAttribute("selected");
       if("true".equals(rootSelValue)){       
         seList.add(rootID); 
       }
     }
     String[] searchFolder=new String[seList.size()];
     for(int i=0;i<seList.size();i++){
       searchFolder[i]=(String)seList.get(i);
     }
     maintForm.setSearchFolder(searchFolder);

     NodeList nameList=doc.getElementsByTagName("name");
     if(nameList.getLength()>0){
       Element nameNode=(Element)nameList.item(0);
       Node nameN=nameList.item(0).getFirstChild();
       String name="";
       if(nameN!=null){
         name=nameN.getNodeValue();
       }
       String nameOption=nameNode.getAttribute("or");    
       String nameExMatch=nameNode.getAttribute("exact_match");
       maintForm.setDocumentName(name);
       if("true".equals(nameOption)){
         maintForm.setDocumentNameOption("OR");
       }else{
         maintForm.setDocumentNameOption("AND");
       }
       maintForm.setDocumentNameExactMatch(TextUtility.parseBoolean(nameExMatch));
     }
     
     NodeList documentTypeList=doc.getElementsByTagName("document_type");
     if(documentTypeList.getLength()>0){
       Element typeNode=(Element)documentTypeList.item(0);
       Node typeN=documentTypeList.item(0).getFirstChild();
       String documentType="";
       if(typeN!=null){
         documentType=typeN.getNodeValue();
       }
       String documentTypeOption=typeNode.getAttribute("or");    
       maintForm.setDocumentType(documentType);
       if("true".equals(documentTypeOption)){
         maintForm.setDocumentTypeOption("OR");
       }else{
         maintForm.setDocumentTypeOption("AND");
       }
     }
     
     NodeList effList=doc.getElementsByTagName("effective_date");  
     if(effList.getLength()>0){
       Element effNode=(Element)effList.item(0);
       String effOption=effNode.getAttribute("or");
       NodeList effSubList=effNode.getElementsByTagName("from");
       NodeList effToSubList=effNode.getElementsByTagName("to");
       String effFromValue="";
       String effToValue="";
       if(effSubList.item(0).getFirstChild()!=null){
         effFromValue=effSubList.item(0).getFirstChild().getNodeValue();
       }
       if(effToSubList.item(0).getFirstChild()!=null){
         effToValue=effToSubList.item(0).getFirstChild().getNodeValue();
       }
       maintForm.setEffectiveStartDate(effFromValue);
       maintForm.setEffectiveEndDate(effToValue);
       if("true".equals(effOption)){
         maintForm.setEffectiveDateOption("OR");
       }else{
         maintForm.setEffectiveDateOption("AND");
       }
     }
  
     NodeList creList=doc.getElementsByTagName("create_date");
     if(creList.getLength()>0){
       Element creNode=(Element)creList.item(0);
       String creOption=creNode.getAttribute("or");
       String creExMatch=creNode.getAttribute("exact_match");     
       NodeList crebList=creNode.getElementsByTagName("from");
       NodeList crebToList=creNode.getElementsByTagName("to");
       String creFromValue="";
       String creToValue="";
       if(crebList.item(0).getFirstChild()!=null){
         creFromValue=crebList.item(0).getFirstChild().getNodeValue();
       }
       if(crebToList.item(0).getFirstChild()!=null){
         creToValue=crebToList.item(0).getFirstChild().getNodeValue();
       }
       maintForm.setCreateDate(creFromValue);
       maintForm.setCreateToDate(creToValue);
       if("true".equals(creOption)){
         maintForm.setCreateDateOption("OR");    
       }else{
         maintForm.setCreateDateOption("AND");
       }
     }
     
     NodeList updList=doc.getElementsByTagName("update_date");
     if(updList.getLength()>0){
       Element updNode=(Element)updList.item(0);
       String updOption=updNode.getAttribute("or");
       NodeList updSubList=updNode.getElementsByTagName("from");
       NodeList updToSubList=updNode.getElementsByTagName("to");
       String updFromValue="";
       String updToValue="";
       if(updSubList.item(0).getFirstChild()!=null){
         updFromValue=updSubList.item(0).getFirstChild().getNodeValue();
       }
       if(updToSubList.item(0).getFirstChild()!=null){
         updToValue=updToSubList.item(0).getFirstChild().getNodeValue();
       }
       if("true".equals(updOption)){
         maintForm.setUpdateDateOption("OR");
       }else{
         maintForm.setUpdateDateOption("AND");
       }
       maintForm.setUpdateDate(updFromValue);
       maintForm.setUpdateToDate(updToValue);
     }
     
     NodeList priList=doc.getElementsByTagName("priority");
     if(priList.getLength()>0){
       Element priNode=(Element)priList.item(0);
       String priValue="";
       if(priList.item(0).getFirstChild()!=null){
         priValue=priList.item(0).getFirstChild().getNodeValue();
       }
       String priOption=priNode.getAttribute("or");
       if("true".equals(priOption)){
         maintForm.setPriorityOption("OR");
       }else{
         maintForm.setPriorityOption("AND");
       }
       maintForm.setSearchPriority(TextUtility.splitString(priValue,","));
     }

     NodeList refList=doc.getElementsByTagName("reference_no");
     if(refList.getLength()>0){
       Element refNode=(Element)refList.item(0);
       String refValue="";
       if(refList.item(0).getFirstChild()!=null){
         refValue=refList.item(0).getFirstChild().getNodeValue();
       }
       String refOption=refNode.getAttribute("or");
       String refExMatch=refNode.getAttribute("exact_match");
       if("true".equals(refOption)){
         maintForm.setReferenceNoOption("OR");
       }else{
         maintForm.setReferenceNoOption("AND");
       }
       maintForm.setReferenceNo(refValue);
       maintForm.setReferenceNoExactMatch(TextUtility.parseBoolean(refExMatch));
     }
     
     NodeList descList=doc.getElementsByTagName("description");
     if(descList.getLength()>0){
       Element descNode=(Element)descList.item(0);
       String descValue="";
       if(descList.item(0).getFirstChild()!=null){
         descValue=descList.item(0).getFirstChild().getNodeValue();
       }
       String descOption=descNode.getAttribute("or");
       String descExMatch=descNode.getAttribute("exact_match");
       if("true".equals(descOption)){
         maintForm.setDescriptionOption("OR");
       }else{
         maintForm.setDescriptionOption("AND");
       }       
       maintForm.setDescription(descValue);
       maintForm.setDescriptionExactMatch(TextUtility.parseBoolean(descExMatch));
     }
     
     NodeList creatorList=doc.getElementsByTagName("creator");
     if(creatorList.getLength()>0){
       Element creatorNode=(Element)creatorList.item(0);
       String creatorValue="";
       if(creatorList.item(0).getFirstChild()!=null){
         creatorValue=creatorList.item(0).getFirstChild().getNodeValue();
       }
       String creatorOption=creatorNode.getAttribute("or");
       if("true".equals(creatorOption)){
         maintForm.setCreatorOption("OR");
       }else{
         maintForm.setCreatorOption("AND");
       }
       maintForm.setCreatorID(creatorValue);
     }
        
     NodeList proList=doc.getElementsByTagName("document_profile");
     if(proList.getLength()>0){
       Element proNode=(Element)proList.item(0);
       String proID=proNode.getAttribute("id");
       String proOption="AND";
       if("true".equals(proNode.getAttribute("or"))){
         proOption="OR";
       }
       maintForm.setUserDefinedFieldID(proID);
       maintForm.setUserDefinedFieldOption(proOption);
     }
     
     NodeList fieldList=doc.getElementsByTagName("field");
     String[] fieldID=new String[fieldList.getLength()];
     String[] fieldName=new String[fieldList.getLength()];
     String[] fieldType=new String[fieldList.getLength()];
     String[] fromValue=new String[fieldList.getLength()];
     String[] toValue=new String[fieldList.getLength()];
     String[] fieldExMatch=new String[fieldList.getLength()];
     String[] fieldOption=new String[fieldList.getLength()];
     for(int i=0;i<fieldList.getLength();i++){
       Element fieldNode=(Element)fieldList.item(i);
       fieldID[i]=fieldNode.getAttribute("id");
       fieldName[i]=fieldNode.getAttribute("name");
       if("true".equals(fieldNode.getAttribute("or"))){
         fieldOption[i]="OR";
       }else{
         fieldOption[i]="AND";
       }
       fieldType[i]=fieldNode.getAttribute("data_type");
       if("S".equals(fieldType[i])){
         fieldExMatch[i]=fieldNode.getAttribute("exact_match");
       }else{
         fieldExMatch[i]=null; 
       }
       NodeList subList=fieldNode.getElementsByTagName("from");
       NodeList subToList=fieldNode.getElementsByTagName("to");
       if(subList.item(0).getFirstChild()!=null){
         fromValue[i]=subList.item(0).getFirstChild().getNodeValue();
       }
       if(subToList.item(0).getFirstChild()!=null){
         toValue[i]=subToList.item(0).getFirstChild().getNodeValue();
       }
     }
     //joan.xiong add code for bug EIP-335 by 2006/09/22
     request.setAttribute("proFieldID",fieldID);
     //joan.xiong add code end
     request.setAttribute("proFieldType",fieldType);
     request.setAttribute("proFromValue",fromValue);
     request.setAttribute("proToValue",toValue);
     request.setAttribute("proFieldOption",fieldOption);
     request.setAttribute("proFieldExMatch",fieldExMatch);
     this.getUserDefValues(doc,maintForm); 
  }
  
  /**
   * Sets the default profile search fields in the form by 
   * the search criteria in the org.w3c.dom.Document
   * 
   * @param doc the org.w3c.dom.Document that store the search criteria
   * @param maintForm the form object to set the search criteria
   */
  protected void getUserDefValues(Document doc,ListDmsDocumentForm maintForm){
    int totalFieldCount = Integer.parseInt(com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DMS_DEFAULT_PROFILE_FIELD_COUNT));
    Method getFileMth=null;
    for(int i=1;i<=totalFieldCount;i++){
      NodeList usfList=doc.getElementsByTagName("user_def_"+i);
      if(usfList.getLength()>0){
        Element usfNode=(Element)usfList.item(0);
        String usfOption="AND";
        if("true".equals(usfNode.getAttribute("or"))){
          usfOption="OR";
        }else{
          usfOption="AND";
        }
        if("S".equals(usfNode.getAttribute("data_type"))){
          String usf1ExMatch=usfNode.getAttribute("exact_match"); 
          maintForm.setUserDef1ExactMatch(TextUtility.parseBoolean(usf1ExMatch));
        }
        NodeList udfSubList=usfNode.getElementsByTagName("from");
        NodeList udfToSubList=usfNode.getElementsByTagName("to");
        String udfFromValue="";
        String udfToValue="";
        if(udfSubList.item(0).getFirstChild()!=null){
          udfFromValue=udfSubList.item(0).getFirstChild().getNodeValue();
        }
        if(udfToSubList.item(0).getFirstChild()!=null){
          udfToValue=udfToSubList.item(0).getFirstChild().getNodeValue();
        }
        try{
        getFileMth = maintForm.getClass().getMethod("setUserDef"+i,new Class[] {String.class}); 
        getFileMth.invoke(maintForm, new Object[] {new String(udfFromValue)}); 
        getFileMth = maintForm.getClass().getMethod("setUserDef"+i+"To",new Class[] {String.class}); 
        getFileMth.invoke(maintForm, new Object[] {new String(udfToValue)}); 
        getFileMth = maintForm.getClass().getMethod("setUserDef"+i+"Option",new Class[] {String.class}); 
        getFileMth.invoke(maintForm, new Object[] {new String(usfOption)}); 
        }catch(NoSuchMethodException ex){
          log.error(ex,ex);
        }catch(IllegalAccessException ee){
          log.error(ee,ee);
        }catch(InvocationTargetException e){
          log.error(e,e);
        }
      }
    } 
  }
  
  /**
   * gets xml tag first value
   * 
   * @param tagName
   * @param elem
   * @return the xml tag value
   */
  public String getTagValue(String tagName,Element elem){
     String s="";
     Element childNode=(Element)elem.getElementsByTagName(tagName).item(0);
     s=((Text)childNode.getFirstChild()).getData().trim();
     return s;
  }
  
  
}